package com.epam.debrecen.hackathon.ai;

import java.util.Iterator;
import java.util.List;
import java.util.Map.Entry;

import com.epam.debrecen.hackathon.Main;
import com.epam.debrecen.hackathon.ai.model.BattleState;
import com.epam.debrecen.hackathon.ai.model.Card;
import com.epam.debrecen.hackathon.ai.model.Cards;
import com.epam.debrecen.hackathon.ai.model.GameState;
import com.epam.debrecen.hackathon.ai.model.Players;
import com.epam.debrecen.hackathon.ai.model.Region;
import com.epam.debrecen.hackathon.ai.model.Regions;
import com.epam.debrecen.hackathon.com.ServerState;

public class Bot {

	private BattleState battleState;
	private final Resolver resolver = new Resolver();
	private final Regions regions;
	private final Cards cards;
	private final Players players;

	public Bot(Regions regions) {
		this.regions = regions;
		this.players = new Players();
		this.cards = new Cards();
	}

	public String evaluateQuestion(ServerState state, String question, GameState gameState) {

		if (Main.DEBUG) {
			System.out.println("------------------------------------");
			System.out.println("State:" + state);
			System.out.println("Question:" + question);
			System.out.println("RegionUnderSiege:" + this.regions.getRegionUnderSiege());
			System.out.println("BishopProtectedRegion:" + this.regions.getBishopProtectedRegion());
		}

		if (state.getCards() != null) {
			for (Entry<String, Card> card : state.getCards().entrySet()) {
				this.cards.addFaceUpCard(card.getKey(), card.getValue());
			}
		}

		if (state.isBishopChange()) {
			cards.removeTopFaceUpCards();
			state.setBishopChange(false);
		}
		if (state.getCurrentPlayer() != null) {
			this.players.addPlayer(state.getCurrentPlayer());
			this.players.setCurrentPlayer(state.getCurrentPlayer());
		}

		if (state.isBattleEnd()) {
			this.cards.flushFaceUpCards();
		}

		if (state.getProtectedRegion() != null) {
			this.regions.setBishopProtected(state.getProtectedRegion(), true);
		}

		// Set owner of region
		if (state.isBattleEnd()) {
			Region regionUnderSiege = this.regions.getRegionUnderSiege();

			if (!"(tie)".equalsIgnoreCase(state.getBattleEndPlayer())) {
				regionUnderSiege.setOwner(state.getBattleEndPlayer());
			}

			regionUnderSiege.setUnderSiege(false);
		}

		if (state.getCurrentZone() != null) {
			this.regions.setUnderSiege(state.getCurrentZone(), true);
		}

		if (state.getHand() != null) {
			this.battleState = new BattleState(state.getHand());
		}

		if (Main.DEBUG) {
			System.out.println("Card:" + this.cards.getFaceUpCards());
		}

		// ?Condottiere zone Reply with the name of the zone where the
		// Condottiere will be placed at.
		if ("?Condottiere".equalsIgnoreCase(question)) {
			String name = this.regions.getNextTarget().getName();
			this.regions.setUnderSiege(name, true);
			return name;
		}

		// ?Move card Reply with the name of the card to be played or pass or
		// drop.
		if ("?Move".equalsIgnoreCase(question)) {
			if (battleState == null) {
				System.out.println("Battlestate was empty, no hand?");
				return "Pass";
			}
			this.battleState.setCards(this.cards);
			this.battleState.setPlayers(this.players);
			this.battleState = (BattleState) this.resolver.process(this.battleState);
			if (this.battleState == null) {

				return "Pass";
			} else {
				Card card = Card.fromName(this.battleState.getSelectedCard());
				this.cards.addFaceUpCard(this.players.getCurrentPlayer(), card);
			}

			return this.battleState.getSelectedCard();
		}

		// ?Bishop zone Reply with the name of the zone where the “Pope” will be
		// placed at or pass if no zone should be protected.
		if ("?Bishop".equalsIgnoreCase(question)) {

			List<Region> possibleRegions = this.regions.getRegionsWithMostFreeNeighbours();
			Region selectedRegion = null;
			for (Region region : possibleRegions) {
				if (!region.isUnderSiege()) {
					selectedRegion = region;
					break;
				}
			}

			if (selectedRegion != null) {
				this.regions.setBishopProtected(selectedRegion.getName(), true);
			}

			cards.removeTopFaceUpCards();


			return (selectedRegion != null) ? selectedRegion.getName() : "Pass";
		}

		// ?Retrieve card Reply with the name of the card to be retrieved from
		// the desk or pass
		if ("?Retrieve".equalsIgnoreCase(question)) {
			Card pickUpCard = null;
			if (this.cards.isWinter()) {
				System.out.println(this.players.getCurrentPlayer());

				List<Card> facedUpCards = this.cards.getFacedUpCards(this.players.getCurrentPlayer());

				System.out.println(facedUpCards);

				for (Card c : facedUpCards) {
					if (c.isMercenary() && c.getValue() > 4) {
						if (pickUpCard == null || c.getValue() > pickUpCard.getValue()) {
							pickUpCard = c;
						}
					}
				}

				if (pickUpCard != null) {
					facedUpCards.remove(pickUpCard);
				}
			}

			return (pickUpCard != null) ? pickUpCard.getName() : "Pass";
		}

		throw new IllegalStateException("Question is not implemeted. Question:" + question);
	}
}
